package Server.ServerCore.Service.service;

import Server.ExtComponents.MyBatis.OrmProviderFactory;
import Server.ExtComponents.socket.ObjectSession;

import Server.ExtComponents.utilsKit.Rnd;
import Server.ExtComponents.utilsKit.util.MD5Util;
import Server.ServerCore.Model.AI.BankerAI;
import Server.ServerCore.Model.Player.PlayerInstance;
import Server.ServerCore.Model.dbsql.mapper.GameRoleMapper;
import Server.ServerCore.Model.dbsql.model.GameRole;
import Server.ServerCore.Model.vo.CardResultStatusVO;
import Server.ServerCore.Model.vo.CardVO;
import Server.ServerCore.Service.hardCode.CardType;
import Server.ServerCore.Service.usyns.SingelTableManager;
import javolution.util.FastList;
import javolution.util.FastMap;
import org.apache.ibatis.session.SqlSession;

import java.util.Map;

public class PlayerManagerService {

    /**在线游戏角色列表* */
    public static final Map<Integer, PlayerInstance> userOnLine = new FastMap<Integer, PlayerInstance>().shared();
    /*****session管理********/
    public static final Map<ObjectSession,PlayerInstance> SESSION_PLAYER_INSTANCE_MAP=new FastMap<ObjectSession,PlayerInstance>().shared();
    private static String[]keys={"1111","2222","3333","4444"};
    /**
     *
     * @return
     */
    public static String getMD5(){
        return MD5Util.MD5(keys[Rnd.newInstance(Rnd.RandomType.UNSECURE_VOLATILE).getInt(0, keys.length - 1)]);
    }

    /**
     * 根据用户的名称获取玩家对象
     *
     * @param userName
     * @return
     */
    public static PlayerInstance getUserbyName(String userName){
        for(Map.Entry<Integer, PlayerInstance> entry : userOnLine.entrySet()){
            if(userName.equals(entry.getValue().getName())){
                return entry.getValue();
            }
        }
        return null;
    }

    /**
     * 根据用户的账号获取玩家对象
     *
     * @param UserAccount
     * @return
     */
    public static PlayerInstance getUserbyUserAccount(String UserAccount){
        for(Map.Entry<Integer, PlayerInstance> entry : userOnLine.entrySet()){
            if(UserAccount.equals(entry.getValue().getUserAccount())){
               return entry.getValue();
            }
        }
        return null;
    }

    /**
     * 返回nextcircleUnitID : 0,1,2,3,4
     * @param player
     * @param circleUnitID   非黑杰克位置，如果是黑杰克，直接
     * @return nextcircleUnitID
     *
     *
     * （0==6）（1=7）（2==8）（3==9）（4==10）
     */
    public static int getNextcircleUnitID(PlayerInstance player,int circleUnitID){
        FastList<Integer> circleUnitIDS=player.getCircleUnitIDS();//有序列表 从小到大
        int nextcircleUnitID=-1;
        if (circleUnitID>=6&&circleUnitID<=10&&circleUnitIDS.contains(circleUnitID)){//返回6,7,8,9,10对应的位置
            if (circleUnitID==6){
                nextcircleUnitID=0;
                return nextcircleUnitID;
            }else if (circleUnitID==7){
                nextcircleUnitID=1;
                return nextcircleUnitID;
            }else if (circleUnitID==8){
                nextcircleUnitID=2;
                return nextcircleUnitID;
            }else if (circleUnitID==9){
                nextcircleUnitID=3;
                return nextcircleUnitID;
            }else if (circleUnitID==10){
                nextcircleUnitID=4;
                return nextcircleUnitID;
            }
        }
        int index=circleUnitIDS.indexOf(circleUnitID);//返回指定值在链表中的位置
        if (index+1<circleUnitIDS.size()){
            nextcircleUnitID=circleUnitIDS.get(index+1);
        }
        //最后一个位置
        if (nextcircleUnitID>4)nextcircleUnitID=-1;
        return nextcircleUnitID;
    }



    public static void update(GameRole gameRole,double lastChips){
        //获取session
        SqlSession Session = OrmProviderFactory.getOrmProviderFactory().getSimpleSqlSession();
        try {
            GameRoleMapper gameAccountMapper=Session.getMapper(GameRoleMapper.class);
            gameRole.setRoleBargainingChip(lastChips);
            gameAccountMapper.updateByPrimaryKey(gameRole);
        }finally {
            Session.close();
        }
    }


    //玩家异常关闭，掉线，刷新网络，游戏服务器自动处理筹码数据，AI托管处理
    public static void DisasterRecovery(PlayerInstance player){
//        System.out.println("---->>>容灾处理.....托管AI");
        //对庄家发牌
        BankerAI bankerAI=SingelTableManager.tableFastList.get(player.getTableID()).getBanker();
        boolean haveInsurance=false;
        CardResultStatusVO[]cardResultStatusVOs=player.getDeckoOfCardsVOFastList();
        if (cardResultStatusVOs!=null){
            for (CardResultStatusVO statusVO:cardResultStatusVOs){
                if (statusVO!=null&&statusVO.getInsurance()==1){
                    haveInsurance=true;//有买保险
                    break;
                }
            }
            if (player.atomicInteger.get()!=0||haveInsurance){

                FastList<CardVO>AIcardVOs=bankerAI.getCardVOFastList();//bankerAI cardVO
                CardVO vo=AIcardVOs.get(0);
                int CardPoint=0;
                if (vo.getCardType().getPoint()==0){
                    for (;;){
                        //如果大于17则break；否则循环产生牌，并且每次产生之后重新计算牌点数
                        if (CardPoint>=17){
                            bankerAI.setPoints(CardPoint);
//                            System.out.println("庄家点数commonsAA-->>>>>："+ (CardPoint));
                            CardPoint=0;
                            break;
                        }else {
                            CardPoint=0;
                            CardVO cardVO=new CardVO();
                            if (cardVO.getCardType().getPoint()==0){//A continue
                                continue;
                            }
                            cardVO.setCircleUnitID(5);
                            AIcardVOs.add(cardVO);

                            //添加一张牌后重新计算牌的点数
                            //计算点数，A+1；
                            for (CardVO c:AIcardVOs){
                                if (c.getCardType().getPoint()==0){//A
                                    CardPoint+=1;
                                }else {
                                    CardPoint+=c.getCardType().getPoint();
                                }
                            }
                            //找A，+10；若大于21则不加10
                            for (CardVO c:AIcardVOs){
                                if (c.getCardType().getPoint()==0){//A
                                    CardPoint=CardPoint+10>21?CardPoint:CardPoint+10;
                                }
                            }
                        }
                    }
                }else {
                    CardPoint=vo.getCardType().getPoint();
                    for (;;){
                        //如果大于17则break；否则循环产生牌，并且每次产生之后重新计算牌点数
                        if (CardPoint>=17){
                            bankerAI.setPoints(CardPoint);
//                            System.out.println("庄家点数commonsAA-->>>>>："+ (CardPoint));
                            CardPoint=0;
                            break;
                        }else {
                            CardPoint=0;
                            CardVO cardVO=new CardVO();
                            if (cardVO.getCardType().getPoint()==0){//A continue
                                continue;
                            }
                            cardVO.setCircleUnitID(5);
                            AIcardVOs.add(cardVO);

                            //添加一张牌后重新计算牌的点数
                            //计算点数，A+1；
                            for (CardVO c:AIcardVOs){
                                if (c.getCardType().getPoint()==0){//A
                                    CardPoint+=1;
                                }else {
                                    CardPoint+=c.getCardType().getPoint();
                                }
                            }
                            //找A，+10；若大于21则不加10
                            for (CardVO c:AIcardVOs){
                                if (c.getCardType().getPoint()==0){//A
                                    CardPoint=CardPoint+10>21?CardPoint:CardPoint+10;
                                }
                            }
                        }
                    }
                }

            }

        }
        //计算玩家牌点数，并结算
        int bankerPoints=bankerAI.getPoints();
        //庄家是否黑杰克
        boolean bankAIBlack=false;
        if ( bankerAI.getCardVOFastList().size()==2&&bankerPoints==21){
            bankAIBlack=true;
        }

        double  totalChips=0;
        for (Integer circleUnitID:player.getCircleUnitIDS()){
            if (player.getDeckoOfCardsVOFastList()!=null){
                CardResultStatusVO cardResultStatusVO=player.getDeckoOfCardsVOFastList()[circleUnitID];
                if (cardResultStatusVO.getBust()!=1){//玩家没有爆牌
                    int playerPoints=getPlayerPoints(player,circleUnitID);
                    byte lost;//0:lost
                    double Chips = 0;
                    double tempChips=cardResultStatusVO.getChipsPoints();//每副牌的筹码数
                    //解析玩家是否是黑杰克 如果庄家和玩家都是黑杰克，那么庄家赢
                    boolean blackPlayer=false;
                    FastList<CardVO> temp1=new FastList<CardVO>();//player blackjack
                    for (CardVO card:player.getCardVOFastList()){
                        if (card.getCircleUnitID()==circleUnitID){
                            temp1.add(card);
                        }
                    }
                    if (temp1.size()==2&&playerPoints==21&&!cardResultStatusVO.isIsspush()){
                        blackPlayer=true;
                    }
                    temp1.clear();
//                1.平手 lost=2；
//                2.庄家赢  lost=0；
//                3.玩家赢  lost=1；  以上3个条件，互斥
                    if (playerPoints==bankerPoints&&bankerPoints<=21&&playerPoints<=21&&!bankAIBlack&&!blackPlayer||blackPlayer&&bankAIBlack){//打和
                        lost=2;
                        Chips=tempChips;

//                        System.out.println("平手--》》"+"庄点数："+ bankerPoints+" 玩家点数："+ playerPoints);

                    }else if (bankerPoints>playerPoints&&bankerPoints<=21&&playerPoints<=21||bankAIBlack&&!blackPlayer){//庄家赢（注意买了保险的玩家）
                        lost=0;
                        Chips=0;
//                        System.out.println("庄家赢--》》"+"庄点数："+ bankerPoints+" 玩家点数："+ playerPoints);

                    }else if (playerPoints>bankerPoints&&playerPoints<=21&&bankerPoints<=21||bankerPoints>21||blackPlayer&&!bankAIBlack){
                        lost=1;
                        if (blackPlayer){
//                            System.out.println("当前牌的筹码数：--->>>>"+tempChips);
                            Chips=tempChips*2.5;
//                            System.out.println("2.5的筹码数：--->>>>"+Chips);

                        }else {
//                            System.out.println("当前牌的筹码数：--->>>>"+tempChips);
                            Chips=tempChips*2;
//                            System.out.println("2倍的筹码数：--->>>>"+Chips);


                        }
//                        System.out.println("玩家赢--》》"+"庄家点数："+ bankerPoints+"玩家点数："+ playerPoints);
                    }
                    totalChips+=Chips;//牌桌筹码

                }
            }else {
                return;
            }
        }
        totalChips+=player.getBargainingChip();//玩家筹码总额
        PlayerManagerService.update(player.getGameRole(), totalChips);

        player.setBargainingChip(totalChips);
        player.setOver(true);
        player.setBet(false);
        PlayerManagerService.clear(player);
//        System.out.println("over筹码余额：--->>>>"+totalChips);





    }

//    tableFastList.get(playerInstance.getTableID()).getBanker()
    public static void update(GameRole gameRole){
        //获取session
        SqlSession Session = OrmProviderFactory.getOrmProviderFactory().getSimpleSqlSession();
        try {
            GameRoleMapper gameAccountMapper=Session.getMapper(GameRoleMapper.class);
            gameAccountMapper.updateByPrimaryKey(gameRole);
        }finally {
            Session.close();
        }
    }

    /**
     * 牌局结束或则爆牌完毕
     * 清理游戏资源
     * @param player
     */
    public static void clear(PlayerInstance player){
        //clear the bankerAI data
        BankerAI banker=SingelTableManager.tableFastList.get(player.getTableID()).getBanker();
        banker.getCardVOFastList().clear();
        player.getCardVOFastList().clear();
        player.getCircleUnitIDS().clear();
        player.setDeckoOfCardsVOFastList(null);
        player.atomicInteger.set(0);
        CardType.resetCard();
    }

    /**
     *  获取玩家circleUnitID位置上的牌点数
     * @param player
     * @param circleUnitID
     * @return
     */
    public static int getPlayerPoints(PlayerInstance player,int circleUnitID){
        FastList<CardVO> playersCardVO=player.getCardVOFastList();
        //计算点数
        int points=0;
        for (CardVO c: playersCardVO){
            if (c.getCircleUnitID()==circleUnitID){
                if (c.getCardType().getPoint()==0){
                    points+=1;
                }else {
                    points+=c.getCardType().getPoint();
                }
            }
        }
        //找A，+10；若大于21则不加10
        for (CardVO c: playersCardVO){
            if (c.getCircleUnitID()==circleUnitID){
                if (c.getCardType().getPoint()==0){
                    points=points+10>21?points:points+10;
                }
            }
        }
        return  points;
    }

//    /**
//     * 计算玩家circleUnitID铺牌的点数，并设置update
//     * @param player
//     * @param circleUnitID
//     */
//    public static void setPlayerPoints(PlayerInstance player,int circleUnitID){
//        int points=getPlayerPoints(player, circleUnitID);
//        if (points>21){
//            player.atomicInteger.decrementAndGet();//爆牌，牌的数量减1
//            //爆牌且没有买保险的 ID
//            CardResultStatusVO[] cardResultStatusVOs=player.getDeckoOfCardsVOFastList();
//            if (cardResultStatusVOs!=null){
//                CardResultStatusVO cardResultStatusVO=cardResultStatusVOs[circleUnitID];
//                if (cardResultStatusVO.getInsurance()!=1){
//                    cardResultStatusVO=null;
//                    for (CardVO cardVO:player.getCardVOFastList()){
//                        if (cardVO.getCircleUnitID()==circleUnitID){
//                            player.getCardVOFastList().remove(cardVO);
//                        }
//                    }
//                }
//                if (circleUnitID==player.getNowCrileUnitID()&&circleUnitID!=5){
//                    player.getDeckoOfCardsVOFastList()[circleUnitID].setBust((byte) 1);
//                    bust_response bustResponse=new bust_response();
//                    int now=PlayerManagerService.getNextcircleUnitID(player, circleUnitID);
//                    bustResponse.setNextcircleUnitID(now);
//                    if (now!=-1){
//                        player.setNowCrileUnitID(now);
//                    }
//                    player.DirectSend(bustResponse.getJsonData(2,9));
//                }
//            }
//        }else {
//            if (player.getCircleUnitIDS().contains(circleUnitID))
//                player.getDeckoOfCardsVOFastList()[circleUnitID].setPoints(points);
//        }
//    }

    public static void main(String[]args){
        FastList<Integer> IDs=new FastList<Integer>();
        IDs.add(1);
        IDs.add(2);
        IDs.add(4);
        IDs.add(6);
        IDs.add(7);
        IDs.add(8);
        IDs.add(10);

//        PlayerInstance playerInstance= new PlayerInstance(null);
//        FastList<Integer> circleUnitIDS=playerInstance.getCircleUnitIDS();

//        playerInstance.setCircleUnitIDS(IDs);
//        int nextID=getNextcircleUnitID(playerInstance,4);
//        IDs.set((IDs.indexOf(7)),0);
        System.out.println(IDs);
        IDs.remove(IDs.indexOf(8));
       System.out.println(IDs);


    }

}
